﻿/*	http://code.google.com/p/wamon/
 *	Windows Activity Monitor - Monitors user's activity on the computer, 
 *	tracks active windows and processes, allows table and chart visualization.
 *	Copyright (C) 2009  Archae s.r.o. (http://archaedev.com/)
 *
 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Drawing;
using System.Resources;
using System.Security.Cryptography;
using System.Text;

namespace Archae.Wamon
{
	class WamonHttp
	{
		private HttpInterface.HttpServer server;
		private ResourceManager resourceManager;

		public WamonHttp()
		{
			server = new HttpInterface.HttpServer();
			server.AddHandler("stats", new HttpInterface.HttpRequestHandlerDelegate(OnStats));
			server.AddHandler("groups", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnGroups));
			server.AddHandler("addgroup", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnAddGroup));
			server.AddHandler("removegroup", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnRemoveGroup));
			server.AddHandler("timesheet", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnTimeSheet));
			server.AddHandler("icon", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnIcon));
			server.AddHandler("process", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnProcess));
			server.AddHandler("add_process", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnAddProcess));
			server.AddHandler("remove_process", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnRemoveProcess));
			server.AddHandler("settings", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnSettings));
			server.AddHandler("setsettings", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnSetSettings));
			server.AddHandler("logo.png", new HttpInterface.HttpRequestHandlerDelegate(OnResource));
			server.AddHandler("prototype.js", new HttpInterface.HttpRequestHandlerDelegate(OnResource));
			server.AddHandler("search", new Archae.HttpInterface.HttpRequestHandlerDelegate(OnSearch));
			try
			{
				resourceManager = new ResourceManager("Archae.Wamon.Properties.Resources", GetType().Assembly);
				Dict.Singleton.Load((string)resourceManager.GetObject("dict_xml"), DB.Singleton.Language);
			}
			catch { }
		}

		public void Start()
		{
			server.Start(DB.Singleton.Port, !DB.Singleton.RemoteAccess);
		}

		public void Stop()
		{
			server.Stop();
		}

		private string Menu
		{
			get
			{
				return "<a href=\"stats\">" + Dict.Singleton["statistics"] + "</a><a href=\"groups\">" +
					Dict.Singleton["groups"] + "</a><a href=\"timesheet\">" + Dict.Singleton["timesheet"] + "</a>" +
					"<a href=\"process\">" + Dict.Singleton["processes"] + "</a>" +
					"<a href=\"settings\">" + Dict.Singleton["settings"] + "</a>";
			}
		}

		private string GetFilterHtml(DateTime time1, DateTime time2, string user, string page)
		{
			string html = "<form method=\"get\" action=\"" + page + "\"><div align=\"center\">" + Dict.Singleton["from"] + " <input type=\"text\" id=\"from\" name=\"from\" value=\"" + time1.ToString("d", Dict.Singleton.CultureInfo) + "\" /> " +
					Dict.Singleton["to"] + " <input type=\"text\" id=\"to\" name=\"to\" value=\"" + time2.ToString("d", Dict.Singleton.CultureInfo) + "\" /> " +
					Dict.Singleton["user"] + " <select name=\"user\" id=\"user\">{options}</select>" +
					" <input type=\"submit\" value=\"" + Dict.Singleton["load"] + "\"  /></div></form>";

			SQLiteDataReader reader = DB.Singleton.GetUsers();
			string option = "<option value=\"all_users\">" + Dict.Singleton["all_users"] + "</option>";
			while (reader.Read())
			{
				string sel = "";
				if (user == (string)reader["user"])
					sel = "selected=\"selected\"";
				option += "<option value=\"" + (string)reader["user"] + "\" " + sel + " >" + (string)reader["user"] + "</option>";
			}
			html = html.Replace("{options}", option);
			reader.Close();
			return html;
		}

		private int OnStats(HttpInterface.HttpReqResp req)
		{
			try
			{
				DateTime time1 = DateTime.Now.AddDays(-5);
				DateTime time2 = DateTime.Now;

				try
				{
					if (req["from"] != null)
						time1 = DateTime.Parse(req["from"], Dict.Singleton.CultureInfo);
					if (req["to"] != null)
						time2 = DateTime.Parse(req["to"], Dict.Singleton.CultureInfo);
				}
				catch
				{
					time1 = DateTime.Now.AddDays(-5);
					time2 = DateTime.Now;
				}
				string html = "";
				string chartQuery = DB.Singleton.GetCharts(time1, time2, req["user"]);
				if (chartQuery == null || chartQuery == string.Empty)
				{
					html += GetFilterHtml(time1, time2, (string)req["user"], "stats");
					html += "<br/><br/><div align=\"center\">" + Dict.Singleton["no_chart"] + "</div>";
				}
				else
				{
					string[] lastActivity = DB.Singleton.GetLastActivity(req["user"]);
					if (lastActivity != null && lastActivity.Length == 2)
					{
						html += "<div style=\"text-align: center; color: #8b9677; font-size: 120%; font-weight: bold; margin-bottom: 20px;\">";
						html += Dict.Singleton["last_activity"] + ": <span style=\"font-size: 130%; color: #3b5607;\">";
						if (lastActivity[0] == "IDLE")
							html += Dict.Singleton["idle"] + "</span></div>";
						else
							html += lastActivity[0] + "</span> (" + lastActivity[1] + ")</div>";
					}
					html += GetFilterHtml(time1, time2, (string)req["user"], "stats");
					html += "<p style='text-align: center;'><img src='" + chartQuery + "'/></p>";
				}

				html = ((string)resourceManager.GetObject("wamon_html"))
					.Replace("{content}", html)
					.Replace("{menu}", Menu)
					.Replace("{title}", Dict.Singleton["wam_statistics"])
					.Replace("{search_button}", Dict.Singleton["search_button"]);
				req.Write(html);
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			catch (Exception e)
			{
				req.Write(e.ToString());
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			return 200;
		}

		private int OnGroups(HttpInterface.HttpReqResp req)
		{
			try
			{
				DateTime time1 = DateTime.Now.AddDays(-5);
				DateTime time2 = DateTime.Now;

				try
				{
					if (req["from"] != null)
						time1 = DateTime.Parse(req["from"], Dict.Singleton.CultureInfo);
					if (req["to"] != null)
						time2 = DateTime.Parse(req["to"], Dict.Singleton.CultureInfo);
				}
				catch
				{
					time1 = DateTime.Now.AddDays(-5);
					time2 = DateTime.Now;
				}
				string html = "";

				string chartQuery = DB.Singleton.GetGroupsCharts(time1, time2, req["user"]);
				if (chartQuery == string.Empty)
				{
					html += GetFilterHtml(time1, time2, (string)req["user"], "groups");
					html += "<br/><br/><div align=\"center\">" + Dict.Singleton["no_chart"] + "</div>";
				}
				else
				{
					string[] lastActivity = DB.Singleton.GetLastActivityGroup(req["user"]);
					if (lastActivity != null && lastActivity.Length == 2)
					{
						html += "<div style=\"text-align: center; color: #8b9677; font-size: 120%; font-weight: bold; margin-bottom: 20px;\">" +
						Dict.Singleton["last_group"] + ": <span style=\"font-size: 130%; color: #3b5607;\">" + lastActivity[0] + "</span> (" + lastActivity[1] + ")</div>";
					}
					html += GetFilterHtml(time1, time2, (string)req["user"], "groups");
					html += "<p style='text-align: center;'><img src='" + chartQuery + "'/></p>";
				}

				html += "<div id=\"heading\"><h1>" + Dict.Singleton["edit_groups"] + "</h1></div><br/>";

				html += "<form method=\"post\" action=\"addgroup\"><div align=\"center\">" +
					Dict.Singleton["name"] + ": <input type=\"text\" name=\"group_name\" id=\"group_name\" /> " +
					Dict.Singleton["window_regular"] + ": <input type=\"text\" name=\"window_regular\" id=\"window_regular\" /> " +
					Dict.Singleton["process_regular"] + ": <input type=\"text\" name=\"process_regular\" id=\"process_regular\" /> " +
					" <input type=\"submit\" value=\"" + Dict.Singleton["add_group"] + "\" " +
					" onclick=\"if($('group_name').value == '' && ($('window_regular').value == '' && $('process_regular').value == '')) return false;\" /></div></form>";
				html += "<table border=\"1\" style=\"width:100%;\"><tr><th>" + Dict.Singleton["group_name"] +
					"</th><th>" + Dict.Singleton["window_regular"] + "</th><th>" +
					Dict.Singleton["process_regular"] + "</th><th>&nbsp;</th></tr>";
				System.Collections.Generic.List<Group> groups = DB.Singleton.GetGroups();
				foreach (Group group in groups)
				{
					html += "<tr><td><div id=\"gr" + group.id.ToString() + "\">" + group.name + "</div></td><td>" +
						((group.windowRegular == null) ? "" : group.windowRegular) + "</td><td>" +
						((group.processRegular == null) ? "" : group.processRegular) + "</td><td>" +
						"<a href=\"removegroup?id=" + group.id + "\" onclick=\" if (!confirm('" +
						Dict.Singleton["remove_group_confirm"] + " ' + $('gr" + group.id.ToString() + "').innerHTML + '?')) " +
						"return false;\">" + Dict.Singleton["remove"] + "</a></td></tr>";
				}
				html += "</table>";
				html = ((string)resourceManager.GetObject("wamon_html"))
					.Replace("{content}", html)
					.Replace("{menu}", Menu)
					.Replace("{title}", Dict.Singleton["wam_groups"])
					.Replace("{search_button}", Dict.Singleton["search_button"]);
				req.Write(html);
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			catch (Exception e)
			{
				req.Write(e.Message);
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			return 200;
		}

		private int OnAddGroup(HttpInterface.HttpReqResp req)
		{
			if (((string)req["group_name"] != null) && ((string)req["group_name"] != string.Empty) &&
				(((string)req["window_regular"] != null && (string)req["window_regular"] != string.Empty) ||
				((string)req["process_regular"] != null && (string)req["process_regular"] != string.Empty)))
			{
				DB.Singleton.AddGroup(new Group(0, (string)req["group_name"], (string)req["window_regular"], (string)req["process_regular"]));
			}
			req.SetHeader("Location", "groups");
			return 301;
		}

		private int OnRemoveGroup(HttpInterface.HttpReqResp req)
		{
			try
			{
				if (req["id"] != null && int.Parse((string)req["id"]) != 0)
				{
					DB.Singleton.RemoveGroup(int.Parse((string)req["id"]));
				}
			}
			catch { }
			req.SetHeader("Location", "groups");
			return 301;
		}

		private int OnTimeSheet(HttpInterface.HttpReqResp req)
		{
			// Load selected or current date
			DateTime time = DateTime.Now;
			try
			{
				if (req["time"] != null)
					time = DateTime.Parse(req["time"], Dict.Singleton.CultureInfo);
			}
			catch { time = DateTime.Now; }

			// Prepare filter HTML
			string html = "<form method=\"get\" action=\"timesheet\"><div align=\"center\">" + Dict.Singleton["day"] +
				": <input type=\"text\" name=\"time\" value=\"" + time.ToString("d", Dict.Singleton.CultureInfo) + "\" /> " +
				Dict.Singleton["user"] + ": <select name=\"user\">{options}</select> " +
				"<input type=\"checkbox\" name=\"wndnames\" id=\"wndnames\" " + (req["wndnames"] == "on" ? "checked=\"checked\" " : "") +
				"/> <label for=\"wndnames\">" + Dict.Singleton["show_window_titles"] + "</label> <input type=\"submit\" value=\"" +
				Dict.Singleton["load"] + "\" /></div></form>";
			// Load all distinct users
			SQLiteDataReader reader = DB.Singleton.GetUsers();
			string option = "<option value=\"all_users\">" + Dict.Singleton["all_users"] + "</option>";
			while (reader.Read())
			{
				string sel = "";
				if ((string)req["user"] == (string)reader["user"])
					sel = "selected=\"selected\"";
				option += "<option value=\"" + (string)reader["user"] + "\" " + sel + " >" + (string)reader["user"] + "</option>";
			}
			html = html.Replace("{options}", option);
			reader.Close();

			SQLiteDataReader r = DB.Singleton.GetTimeSheet(time, (string)req["user"]);
			html += "<table style=\"position: relative; left: 50px; line-height: 130%; width:100%;\">";
			DateTime lastTime = time.AddDays(-1);
			DateTime groupedStartTime = DateTime.MinValue;
			string lastProcess = string.Empty;
			while (r.Read())
			{
				string currProcess = (string)r[req["wndnames"] == "on" ? "window" : "process"];
				DateTime currTime = DateTime.Parse((string)r["time"]);
				if (currProcess == lastProcess && (currTime - lastTime).TotalMinutes <= 2)
				{
					lastTime = currTime;
					if (groupedStartTime == DateTime.MinValue)
						groupedStartTime = currTime;
					continue;
				}
				else if (lastProcess != string.Empty && (currTime - lastTime).TotalMinutes > 2)
				{
					if (groupedStartTime != DateTime.MinValue && (lastTime - groupedStartTime).TotalMinutes >= 2)
					{
						string formins = String.Format(Dict.Singleton["for_x_mins"], (int)(lastTime - groupedStartTime).TotalMinutes);
						html += "<tr><td>&nbsp;</td><td nowrap=\"nowrap\" style=\"color: #8b9677; padding-left: 30px;\" >" + formins + "</td></tr>";
						groupedStartTime = DateTime.MinValue;
					}
					html += "<tr><td style=\"text-align:left;  color: #8b9677; padding-left: 15px; padding-bottom:10px; font-size:140%\">|</td><td>&nbsp;</td></tr>";
				}
				lastProcess = currProcess;
				lastTime = currTime;
				string fileDesc = (currProcess == "IDLE" ? Dict.Singleton["idle"] : (string)DB.Singleton.GetFileDescription(currProcess));
				if (fileDesc == null)
					fileDesc = currProcess;

				if (groupedStartTime != DateTime.MinValue && (lastTime - groupedStartTime).TotalMinutes >= 2)
				{
					string formins = String.Format(Dict.Singleton["for_x_mins"], (int)(lastTime - groupedStartTime).TotalMinutes);
					html += "<tr><td>&nbsp;</td><td nowrap=\"nowrap\" style=\"color: #8b9677; padding-left: 30px;\" >" + formins + "</td></tr>";
					groupedStartTime = DateTime.MinValue;
				}
				html += "<tr><td style=\"width:80px; color: #8b9677;\">" + lastTime.ToString("hh:mmtt").ToLower() + "</td><td><img src=\"icon?process=" + (string)r["process"] + "\"> " + fileDesc + "</td></tr>";
			}
			if (groupedStartTime != DateTime.MinValue && (lastTime - groupedStartTime).TotalMinutes >= 2)
			{
				string formins = String.Format(Dict.Singleton["for_x_mins"], (int)(lastTime - groupedStartTime).TotalMinutes);
				html += "<tr><td>&nbsp;</td><td nowrap=\"nowrap\" style=\"color: #8b9677; padding-left: 30px; \" >" + formins + "</td></tr>";
			}

			html += "</table>";
			r.Close();
			html = ((string)resourceManager.GetObject("wamon_html"))
					.Replace("{content}", html)
					.Replace("{menu}", Menu)
					.Replace("{title}", Dict.Singleton["wam_timesheet"])
					.Replace("{search_button}", Dict.Singleton["search_button"]);
			req.Write(html);
			req.SetHeader("Content-Type", "text/html; charset=utf-8");
			return 200;
		}

		private int OnIcon(HttpInterface.HttpReqResp req)
		{
			Bitmap icon;
			try
			{
				if (req["process"] == "IDLE")
					icon = Properties.Resources.idle;
				else
					icon = ResizeBitmap(Icon.ExtractAssociatedIcon((string)req["process"]).ToBitmap(), 16, 16);
			}
			catch { icon = new Bitmap(16, 16); }
			icon.Save(req.Response, System.Drawing.Imaging.ImageFormat.Png);
			req.SetHeader("Content-Type", "image/png");
			return 200;
		}

		private Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight)
		{
			Bitmap result = new Bitmap(nWidth, nHeight);
			using (Graphics g = Graphics.FromImage((Image)result))
				g.DrawImage(b, 0, 0, nWidth, nHeight);
			return result;
		}

		private int OnProcess(HttpInterface.HttpReqResp req)
		{
			try
			{
				DateTime time1 = DateTime.Now.AddDays(-5);
				DateTime time2 = DateTime.Now;

				try
				{
					if (req["from"] != null)
						time1 = DateTime.Parse(req["from"], Dict.Singleton.CultureInfo);
					if (req["to"] != null)
						time2 = DateTime.Parse(req["to"], Dict.Singleton.CultureInfo);
				}
				catch
				{
					time1 = DateTime.Now.AddDays(-5);
					time2 = DateTime.Now;
				}
				string html = "<p>" + Dict.Singleton["description_processes"] + "</p>";
				html += GetFilterHtml(time1, time2, (string)req["user"], "process");

				html += DB.Singleton.GetProcessSnapshots(time1, time2, (string)req["user"]);

				html += "<br/><br/><form method=\"GET\" action=\"add_process\"><div align=\"center\">" +
					Dict.Singleton["process_name"] + ": <input type=\"text\" name=\"name\" id=\"name\" /> " +
					"<input type=\"submit\" value=\"" + Dict.Singleton["save"] + "\" onclick=\"if($('name').value == '') return false;\" />" +
					"</div></form>";

				html = ((string)resourceManager.GetObject("wamon_html"))
					.Replace("{content}", html)
					.Replace("{menu}", Menu)
					.Replace("{title}", Dict.Singleton["wam_process"])
					.Replace("{search_button}", Dict.Singleton["search_button"]);
				req.Write(html);
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			catch { }
			return 200;
		}

		private int OnAddProcess(HttpInterface.HttpReqResp req)
		{
			try
			{
				if ((string)req["name"] != null && (string)req["name"] != string.Empty)
					DB.Singleton.AddProcess((string)req["name"]);
			}
			catch { }
			req.SetHeader("Location", "process");
			return 301;
		}

		private int OnRemoveProcess(HttpInterface.HttpReqResp req)
		{
			try
			{
				if (req["id"] != null && int.Parse((string)req["id"]) != 0)
				{
					DB.Singleton.RemoveProcess(int.Parse((string)req["id"]));
				}
			}
			catch { }
			req.SetHeader("Location", "process");
			return 301;
		}

		private int OnSettings(HttpInterface.HttpReqResp req)
		{
			try
			{
				string remoteCheck = (DB.Singleton.RemoteAccess ? "checked=\"checked\" " : "");
				string idleCheck = (DB.Singleton.RecordIdle ? "checked=\"checked\" " : "");

				string html = "<form method=\"post\" action=\"setsettings\"><table border=\"0\" >" +
					"<tr><td style=\"width:300px;\">" + Dict.Singleton["language"] +
					":</td><td><select name=\"language\">{options}</select></td></tr>" +
					"<tr><td><label for=\"port\">" + Dict.Singleton["port_number"] + "</label>:</td><td><input type=\"text\" name=\"port\" id=\"port\" value=\"" + DB.Singleton.Port + "\" /></td></tr>" +
					"<tr><td><label for=\"history\">" + Dict.Singleton["days_to_keep_history"] + "</label>:</td><td><input type=\"text\" name=\"history\" id=\"history\" value=\"" + DB.Singleton.HistoryDays + "\" /></td></tr>" +
					"<tr><td><label for=\"remote\">" + Dict.Singleton["remote_access"] + "</label>:</td><td><input type=\"checkbox\" name=\"remote\" id=\"remote\" " + remoteCheck + "/></td></tr>" +
					"<tr><td><label for=\"idle\">" + Dict.Singleton["record_idle"] + "</label>:</td><td><input type=\"checkbox\" name=\"idle\" id=\"idle\" " + idleCheck + "/></td></tr>" +
					"<tr><td><label for=\"password\">" + Dict.Singleton["password"] + "</label>:</td><td><input type=\"password\" name=\"password\" id=\"password\" /></td></tr>" +
					"<tr><td><label for=\"retry_password\">" + Dict.Singleton["retype_password"] + ":</td><td><input type=\"password\" name=\"retry_password\" id=\"retry_password\" /></td></tr>" +
					"{clear_password}<tr><td>&nbsp;</td><td>&nbsp;</td></tr>" +
					"<tr><td>{password_desc}</td><td>{password_textbox} <input type=\"submit\" value=\"" + Dict.Singleton["save"] + "\" " +
					"onclick=\"if ($('password').value == $('retry_password').value) {return true;} " +
					"alert('" + Dict.Singleton["password_no_equal"] + "'); return false; \" /></td></tr>" +
					"</table></form>";
				if (DB.Singleton.Password != null)
				{
					html = html.Replace("{password_textbox}", "<input type=\"password\" name=\"password_save\" />")
						.Replace("{clear_password}", "<tr><td><label for=\"clear_password\">" + Dict.Singleton["clear_password"] + ":</td><td><input type=\"checkbox\" name=\"clear_password\" id=\"clear_password\" /></td></tr>")
						.Replace("{password_desc}", Dict.Singleton["enter_password"]);
				}
				else
				{
					html = html.Replace("{password_textbox}", "").Replace("{clear_password}", "").Replace("{password_desc}", "");
				}
				string options = "";
				foreach (KeyValuePair<string, string> lang in Dict.Singleton.SupportedLanguages)
				{
					string sel = "";
					if (Dict.Singleton.Language == lang.Key)
						sel = "selected=\"selected\"";
					options += "<option value=\"" + lang.Key + "\"" + sel + ">" + lang.Value + "</option>";
				}

				html = ((string)resourceManager.GetObject("wamon_html"))
					.Replace("{content}", html)
					.Replace("{menu}", Menu)
					.Replace("{title}", Dict.Singleton["wam_settings"])
					.Replace("{search_button}", Dict.Singleton["search_button"])
					.Replace("{options}", options);
				req.Write(html);
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			catch (Exception e)
			{
				req.Write(e.ToString());
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			return 200;
		}

		private int OnSetSettings(HttpInterface.HttpReqResp req)
		{
			bool portChanged = false;
			try
			{
				if (DB.Singleton.Password == null || CalculateSHA1((string)req["password_save"], Encoding.UTF8) == DB.Singleton.Password)
				{
					DB.Singleton.Language = (string)req["language"];
					Dict.Singleton.Language = (string)req["language"];
					try
					{
						int port = int.Parse((string)req["port"]);
						if (port > 0 && port < 65535)
						{
							DB.Singleton.Port = port;
							portChanged = true;
						}
					}
					catch { }
					try { DB.Singleton.HistoryDays = int.Parse((string)req["history"]); }
					catch { }

					DB.Singleton.RemoteAccess = ((string)req["remote"] == "on");
					DB.Singleton.RecordIdle = ((string)req["idle"] == "on");
					if ((string)req["password"] != null && (string)req["password"] != string.Empty)
						DB.Singleton.Password = CalculateSHA1((string)req["password"], Encoding.UTF8);
					if ((string)req["clear_password"] == "on")
						DB.Singleton.DeletePassword();
				}
			}
			catch { }
			if (!portChanged)
				req.SetHeader("Location", "settings");
			else
			{
				int port = int.Parse((string)req["port"]);
				req.SetHeader("Location", "http://" + req.Host + ":" + (string)req["port"] + "/settings");
				server.Stop();
				server.Start(port, !DB.Singleton.RemoteAccess);
			}
			return 301;
		}

		private int OnResource(HttpInterface.HttpReqResp req)
		{
			try
			{
				req.Write((byte[])resourceManager.GetObject(req.Script.Replace('.', '_')));
				req.SetHeader("Content-Type", req.Script.EndsWith(".png") ? "image/png" : "text/javascript");
			}
			catch { }
			return 200;
		}

		private int OnSearch(HttpInterface.HttpReqResp req)
		{
			try
			{
				string html = "";
				SQLiteDataReader reader = DB.Singleton.Search((string)req["q"]);
				if (reader.HasRows)
				{
					html += "<table border=\"0\">";
					int i = 0;
					string temp = "";
					DateTime tempTime = DateTime.MinValue;
					while (reader.Read() && i < 100)
					{
						if (temp == (string)reader["process"] && tempTime.AddMinutes(-2) <= DateTime.Parse((string)reader["time"]))
						{
							tempTime = DateTime.Parse((string)reader["time"]);
							continue;
						}
						i++;
						temp = (string)reader["process"];
						tempTime = DateTime.Parse((string)reader["time"]);
						string fileDesc = DB.Singleton.GetFileDescription((string)reader["process"]);
						if (fileDesc == null)
							fileDesc = (string)reader["process"];
						html += "<tr><td style=\"width:230px; color: #8b9677;\">" + tempTime.ToString(Dict.Singleton.CultureInfo) + "</td><td><img src=\"icon?process=" + (string)reader["process"] + "\"> " + fileDesc + "</td></tr>";
						html += "<tr><td>&nbsp;</td><td style=\"color: #8b9677; padding-left: 30px;\" >" + (string)reader["window"] + "</td></tr>";
					}
					reader.Close();
					html += "</table>";
				}
				else
				{
					html += "<div align=\"center\">" + Dict.Singleton["no_result"] + "</div>";
				}
				html = ((string)resourceManager.GetObject("wamon_html"))
					.Replace("{content}", html)
					.Replace("{menu}", Menu)
					.Replace("{title}", Dict.Singleton["wam_search"])
					.Replace("{search_button}", Dict.Singleton["search_button"]);
				req.Write(html);
				req.SetHeader("Content-Type", "text/html; charset=utf-8");
			}
			catch { }
			return 200;
		}

		private string CalculateSHA1(string text, Encoding enc)
		{
			byte[] buffer = enc.GetBytes(text);
			SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
			string hash = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");
			return hash;
		}
	}
}
